import { baseChildrenBuilder, EOChild } from "./childrenBuilder";
import { mve, onceLife, BuildResult, InitResult, OnceInitDestry, orRun, LifeModelReturn, newLifeModel, Watcher } from "./util"




class CacheViewModel<T>{
	constructor(
		public readonly row: mve.Value<T>,
		private readonly life: LifeModelReturn,
		private readonly result: BuildResult
	) { }
	private once = new OnceInitDestry()
	init() {
		this.once.init()
		this.resultDestroy = orRun(this.result)
	}
	private resultDestroy: InitResult
	destroy() {
		this.once.destroy()
		this.life.destroy()
		orRun(this.resultDestroy)
	}
}
/**
 * 有缓存mvc
 * @param array 
 * @param fun 
 * @returns 
 */
export function filterCacheChildren<T, EO>(
	array: () => T[],
	fun: (me: mve.LifeModel, row: () => T, index: number) => EOChild<EO>
): EOChild<EO> {
	return function (parent, me) {
		const views: CacheViewModel<T>[] = []
		const life = onceLife(function () {
			const size = views.length
			for (let i = 0; i < size; i++) {
				views[i].init()
			}
			return function () {
				const size = views.length
				for (let i = size - 1; i > -1; i--) {
					views[i].destroy()
				}
				views.length = 0
				w.disable()
			}
		})
		const w = Watcher.ofAfter(array, function (vs) {
			if (vs.length < views.length) {
				//更新旧数据视图
				for (let i = 0; i < vs.length; i++) {
					views[i].row(vs[i])
				}
				const minLength = vs.length - 1
				for (let i = views.length - 1; i > minLength; i--) {
					//销毁
					if (life.isInit) {
						views[i].destroy()
					}
					//删除视图
					parent.remove(i)
				}
				views.length = vs.length
			} else {
				//更新旧数据
				for (let i = 0; i < views.length; i++) {
					views[i].row(vs[i])
				}
				//追加新数据
				for (let i = views.length; i < vs.length; i++) {
					const row = mve.valueOf(vs[i])
					const lifeModel = newLifeModel()
					//创建视图
					const vm = parent.newChildAt(i)
					const cs = fun(lifeModel.me, row, i)
					const vx = baseChildrenBuilder(lifeModel.me, cs, vm)
					const cv = new CacheViewModel(row, lifeModel, vx)
					//模型增加
					views.push(cv)
					//初始化
					if (life.isInit) {
						cv.init()
					}
				}
			}
		})
		return life.init
	}
}